package com.kakarote.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.kakarote.admin.entity.BO.AdminMessageQueryBO;
import com.kakarote.admin.entity.PO.AdminMessage;
import com.kakarote.admin.entity.VO.AdminMessageVO;
import com.kakarote.admin.mapper.AdminMessageMapper;
import com.kakarote.admin.service.IAdminMessageService;
import com.kakarote.core.common.cache.CrmCacheKey;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.feign.admin.entity.AdminMessageBO;
import com.kakarote.core.feign.admin.entity.AdminMessageContentBO;
import com.kakarote.core.feign.admin.entity.AdminMessageEnum;
import com.kakarote.core.feign.oa.OaService;
import com.kakarote.core.feign.oa.entity.ExamineVO;
import com.kakarote.core.redis.Redis;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 系统消息表 服务实现类
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-04-27
 */
@Service
public class AdminMessageServiceImpl extends BaseServiceImpl<AdminMessageMapper, AdminMessage> implements IAdminMessageService {
    @Autowired
    private Redis redis;


    /**
     * 新增或修改消息
     *
     * @param message message
     */
    @Override
    public Long saveOrUpdateMessage(com.kakarote.core.feign.admin.entity.AdminMessage message) {
        AdminMessage adminMessage = BeanUtil.copyProperties(message, AdminMessage.class);
        adminMessage.setCreateTime(LocalDateTimeUtil.now());
        saveOrUpdate(adminMessage);
        return adminMessage.getMessageId();
    }

    /**
     * 查询消息列表
     *
     * @param adminMessageBO 搜索对象
     * @return data
     */
    @Override
    public BasePage<AdminMessage> queryList(AdminMessageQueryBO adminMessageBO) {
        adminMessageBO.setUserId(UserUtil.getUserId());
        BasePage<AdminMessage> adminMessageBasePage = getBaseMapper().queryList(adminMessageBO.parse(), adminMessageBO);
        if (Arrays.asList(AdminMessageEnum.CRM_CUSTOMER_IMPORT.getType(), AdminMessageEnum.CRM_CONTACTS_IMPORT.getType(), AdminMessageEnum.CRM_LEADS_IMPORT.getType(), AdminMessageEnum.CRM_PRODUCT_IMPORT.getType()).contains(adminMessageBO.getType())) {
            adminMessageBasePage.getList().forEach(data -> {
                if (StrUtil.isEmpty(data.getTitle())) {
                    data.setTitle("0");
                }
                Map<String, String> keyMap = new HashMap<>();
                if (!AdminMessageEnum.parse(data.getTitle()).equals(AdminMessageEnum.NULL)) {
                    keyMap.put("tittle_resourceKey", "admin.config.message." + data.getTitle());
                }
                data.setLanguageKeyMap(keyMap);
            });
        }
        return adminMessageBasePage;
    }

    /**
     * 查询未读消息数量
     *
     * @return data
     */
    @Override
    public AdminMessageVO queryUnreadCount() {
        return getBaseMapper().queryUnreadCount(UserUtil.getUserId());
    }

    /**
     * 新增消息
     *
     * @param adminMessageBO message
     */
    @Override
    public void addMessage(AdminMessageBO adminMessageBO) {
        if (adminMessageBO.getIds().isEmpty()) {
            return;
        }
        AdminMessageEnum messageEnum = AdminMessageEnum.parse(adminMessageBO.getMessageType());
        addCommonMessage(messageEnum, adminMessageBO);
    }


    private void addCommonMessage(AdminMessageEnum messageEnum, AdminMessageBO adminMessageBO) {
        List<AdminMessage> messageList = new ArrayList<>();
        adminMessageBO.getIds().forEach(id -> {
            AdminMessage adminMessage = new AdminMessage();
            adminMessage.setCreateTime(LocalDateTimeUtil.now());
            if(adminMessageBO.getUserId() == null) {
                adminMessageBO.setUserId(UserUtil.getUserId());
            }
            adminMessage.setCreateUser(adminMessageBO.getUserId());
            adminMessage.setType(messageEnum.getType());
            adminMessage.setLabel(messageEnum.getLabel());
            adminMessage.setTitle(adminMessageBO.getTitle());
            adminMessage.setContent(adminMessageBO.getContent());
            adminMessage.setRecipientUser(id);
            adminMessage.setTypeId(adminMessageBO.getTypeId());
            adminMessage.setContent(setContent(messageEnum, adminMessageBO.getTypeId(), adminMessageBO.getContent(), adminMessage, adminMessageBO.getExamineReason()));
            if(Objects.equals(AdminMessageEnum.CRM_PAYMENT_DUE_NOTICE_MESSAGE.getType(),adminMessageBO.getMessageType())){
                adminMessage.setCreateUserId(0L);
            }
            messageList.add(adminMessage);
        });
        saveBatch(messageList);
    }


    /**
     * 加工消息列表预览详情数据
     *
     * @param messageEnum 消息类型
     * @param typeId      消息来源数据ID
     * @param refuse      审批拒绝使用：拒绝原因
     * @return
     */
    private String setContent(AdminMessageEnum messageEnum, Long typeId, String refuse, AdminMessage adminMessage, String examineReason) {
        AdminMessageContentBO adminMessageContentBO = new AdminMessageContentBO();
        adminMessageContentBO.setRemarks(refuse);
        switch (messageEnum) {
            case OA_EXAMINE_NOTICE:
            case OA_EXAMINE_REJECT:
            case OA_EXAMINE_RESTORE:
            case OA_UNDERWAY_EXAMINE_REJECT:
            case OA_UNDERWAY_EXAMINE_RESTORE:
            case OA_EXAMINE_PASS:
                ExamineVO data = ApplicationContextHolder.getBean(OaService.class).getOaExamineInfo(typeId.toString()).getData();
                adminMessageContentBO.setMoney(data.getMoney());
                adminMessageContentBO.setStartTime(LocalDateTimeUtil.formatNormal(data.getStartTime()));
                adminMessageContentBO.setEndTime(LocalDateTimeUtil.formatNormal(data.getEndTime()));
                adminMessageContentBO.setContent(data.getContent());
                adminMessageContentBO.setRemarks(refuse);
                adminMessageContentBO.setDuration(data.getDuration());
                adminMessageContentBO.setType(data.getType());
                adminMessageContentBO.setExamineName(data.getCategoryTitle());
                break;
        /*    case CRM_CONTRACT_COPY:
                Map<String, Object>  contractInfo = getBaseMapper().queryContract(typeId);
                adminMessage.setTitle(String.valueOf(contractInfo.get("num")));
                break;
            case CRM_RECEIVABLES_COPY:
                Map<String, Object> receivablesInfo = getBaseMapper().queryReceivables(typeId);
                adminMessage.setTitle(String.valueOf(receivablesInfo.get("number")));
                break;
            case CRM_INVOICE_COPY:
                Map<String, Object> invoiceInfo = getBaseMapper().queryInvoice(typeId);
                adminMessage.setTitle(String.valueOf(invoiceInfo.get("invoiceApplyNumber")));
                break;*/
            case OA_EXAMINE_COPY:
                ExamineVO copy = ApplicationContextHolder.getBean(OaService.class).getOaExamineInfo(typeId.toString()).getData();
                adminMessageContentBO.setMoney(copy.getMoney());
                adminMessageContentBO.setStartTime(LocalDateTimeUtil.formatNormal(copy.getStartTime()));
                adminMessageContentBO.setEndTime(LocalDateTimeUtil.formatNormal(copy.getEndTime()));
                adminMessageContentBO.setContent(copy.getContent());
                adminMessageContentBO.setRemarks(refuse);
                adminMessageContentBO.setDuration(copy.getDuration());
                adminMessageContentBO.setType(copy.getType());
                adminMessageContentBO.setExamineName(copy.getCategoryTitle());
                break;
            case CRM_FLOW_EXPORT:
            case CRM_FLOW_PASS:
            case CRM_FLOW_REJECT:
            case CRM_UNDERWAY_FLOW_REJECT:
            case CRM_UNDERWAY_FLOW_RESTORE:
            case CRM_FLOW_RESTORE:
                Map<String, Object> flowData = getBaseMapper().queryData(typeId);
                if (flowData == null) {
                    flowData = getBaseMapper().queryScrmData(typeId);
                }
                adminMessageContentBO.setType(flowData.get("label"));
                adminMessageContentBO.setName(flowData.get("flowName").toString());
                adminMessage.setTitle(flowData.get("name").toString());
                adminMessage.setTypeId(typeId);
                break;
            case CRM_FLOW_COPY:
                Map<String, Object> flowInfo = getBaseMapper().queryData(typeId);
                if (flowInfo == null) {
                    flowInfo = getBaseMapper().queryScrmData(typeId);
                }
                adminMessageContentBO.setType(flowInfo.get("label"));
                adminMessageContentBO.setName(flowInfo.get("flowName").toString());
                adminMessage.setTitle(flowInfo.get("name").toString());
                adminMessage.setTypeId(typeId);
                break;
            // 客户团队成员审批申请
            case CRM_CUSTOMER_TEAM_WAIT:
            case CRM_CUSTOMER_TEAM_REJECT:
            case CRM_CUSTOMER_TEAM_PASS:
            case CRM_CUSTOMER_TEAM:
                Map<String, Object> customer;
                if (redis.exists(CrmCacheKey.CRM_ADMIN_MESSAGE + typeId)) {
                    customer = redis.get(CrmCacheKey.CRM_ADMIN_MESSAGE + typeId);
                } else {
                    customer = getBaseMapper().queryCustomer(typeId);
                }
                if (ObjectUtil.isNotEmpty(customer)) {
                    adminMessageContentBO.setCustomer(new JSONObject().fluentPut("id", StrUtil.toString(customer.get("customerId"))).fluentPut("name", StrUtil.toString(customer.get("customerName"))));
                }
                if (StrUtil.isNotEmpty(examineReason)) {
                    adminMessageContentBO.setExamineReason(examineReason);
                }
                break;
            default:
                return adminMessage.getContent();
        }
        return JSONObject.toJSONString(adminMessageContentBO);
    }

    @Override
    public void deleteEventMessage(Integer eventId) {
        lambdaUpdate().eq(AdminMessage::getLabel, AdminMessageEnum.OA_EVENT_MESSAGE.getLabel())
                .eq(AdminMessage::getType, AdminMessageEnum.OA_EVENT_MESSAGE.getType())
                .apply("create_time > now()").eq(AdminMessage::getTypeId, eventId).remove();
    }

    @Override
    public void deleteById(Long messageId) {
        removeById(messageId);
    }

    @Override
    public void deleteByLabel(Integer label) {
        lambdaUpdate().eq(AdminMessage::getLabel, label).remove();
    }

    @Override
    public void deleteTypeIdMessage(Long typeId, AdminMessageEnum adminMessageEnum) {
        lambdaUpdate().eq(ObjectUtil.isNotEmpty(adminMessageEnum), AdminMessage::getLabel, adminMessageEnum.getLabel())
                .eq(ObjectUtil.isNotEmpty(adminMessageEnum), AdminMessage::getType, adminMessageEnum.getType())
                .apply(ObjectUtil.isNotEmpty(adminMessageEnum), "create_time > now()").eq(AdminMessage::getTypeId, typeId).remove();
    }
}
